#include "shareheader.h"
#include "configview.h"
#include "tranitem.h"
#include "timesettingwid.h"
#include "plotview.h"

ConfigView::ConfigView(ConfigData *data, QWidget *parent) :
    QWidget(parent),
    m_configData(data)
{
    this->Initialize();
    this->SetupUI();
	m_configData->registerObserver(this);
}

ConfigView::~ConfigView()
{
}

void ConfigView::Initialize()
{
    m_configController = new ConfigController(m_configData, this);
}

void ConfigView::SetupUI()
{
    QVBoxLayout *mainLayout = new QVBoxLayout(this);

    // add tran items
    tranList = new QListWidget(this);
    tranList->setSelectionMode(QAbstractItemView::NoSelection);

    for(int i = 0; i < N_TRANSACTIONS; i ++){
        QListWidgetItem *listItem = new QListWidgetItem(tranList);
        listItem->setSizeHint(QSize(35, 35));
        TranItem *item = new TranItem(i);
        tranList->setItemWidget(listItem, item);

        QObject::connect(item, SIGNAL(checkChanged(int,bool)), this, SLOT(CheckHandle(int, bool)));
        QObject::connect(item, SIGNAL(ratioChanged(int,int)), this, SLOT(RatioHandle(int, int)));
    }

    mainLayout->addWidget(tranList);
    QFrame *line = new QFrame();
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    mainLayout->addWidget(line);

    // add time setting widget
    timeSetting = new TimeSettingWid();
    QObject::connect(timeSetting, SIGNAL(durationChanged(int)), this, SLOT(DurationHandle(int)));
    QObject::connect(timeSetting, SIGNAL(userChanged(int)), this, SLOT(UserHandle(int)));
    QObject::connect(timeSetting, SIGNAL(timeChanged(int)), this, SLOT(TimeHandle(int)));
    mainLayout->addWidget(timeSetting);
    line = new QFrame();
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    mainLayout->addWidget(line);

    // add gen man list widget
    genList = new QListWidget(this);
    genList->setSelectionMode(QAbstractItemView::NoSelection);
    mainLayout->addWidget(genList);

    // add add gen button
    QHBoxLayout *hLayout = new QHBoxLayout();
    QPushButton *addGenButton = new QPushButton("Add");
    QObject::connect(addGenButton, SIGNAL(clicked()), this, SLOT(AddGenHandle()));
    hLayout->addWidget(addGenButton);
    hLayout->setAlignment(addGenButton, Qt::AlignRight);
    mainLayout->addLayout(hLayout);

	// add server ip and update rate
	QHBoxLayout *hLayout2 = new QHBoxLayout();
	QLabel *ipLabel = new QLabel("IP:");
	ipLineEdit = new QLineEdit();
	ipLineEdit->setFixedWidth(120);
		// init
	ipLineEdit->setText(QString(m_configData->getServerIP().c_str()));
	QObject::connect(ipLineEdit, SIGNAL(editingFinished()), this, SLOT(SetServerIPHandle()));
	QLabel *updateLabel = new QLabel("Rate:");
	updateLineEdit = new QLineEdit();
	updateLineEdit->setMaximumWidth(50);
		// init
	updateLineEdit->setText(QString::number(m_configData->getUpdateRate() * 5));
	QObject::connect(updateLineEdit, SIGNAL(editingFinished()), this, SLOT(SetUpdateRateHandle()));
	hLayout2->addWidget(ipLabel);
	hLayout2->addWidget(ipLineEdit);
	hLayout2->addWidget(updateLabel);
	hLayout2->addWidget(updateLineEdit);
    mainLayout->addLayout(hLayout2);

	// add a gen man item
	//this->AddGenHandle();
}

void ConfigView::addGen(int genId)
{
    // add an item on the view
    QListWidgetItem *listItem = new QListWidgetItem(genList);
    listItem->setSizeHint(QSize(35, 35));
    GenManItem *genManItem = new GenManItem();
	QObject::connect(genManItem, SIGNAL(delGen(int)), this, SLOT(DelGenHandle(int)));
	QObject::connect(genManItem, SIGNAL(genConfigChanged(int, const TGenConfig&)), this, SLOT(GenConfigHandle(int, const TGenConfig&)));
    genManItem->setGenId(genId);
    genList->setItemWidget(listItem, genManItem);
}

void ConfigView::addGen(int genId, const TGenConfig& config)
{
    // add an item on the view
    QListWidgetItem *listItem = new QListWidgetItem(genList);
    listItem->setSizeHint(QSize(35, 35));
    GenManItem *genManItem = new GenManItem();
	genManItem->setGenConfig(config);
	QObject::connect(genManItem, SIGNAL(delGen(int)), this, SLOT(DelGenHandle(int)));
	QObject::connect(genManItem, SIGNAL(genConfigChanged(int, const TGenConfig&)), this, SLOT(GenConfigHandle(int, const TGenConfig&)));
    genManItem->setGenId(genId);
    genList->setItemWidget(listItem, genManItem);
}

void ConfigView::delGen(int genId)
{
    // delete from view
    GenManItem *genItem = NULL;
    int i;
    for(i = 0; i < genList->count(); i ++){
        genItem = (GenManItem *)(genList->itemWidget(genList->item(i)));
        if( genItem->getGenId() == genId) break;
    }
    if(i >= genList->count()) return; // not found
    QListWidgetItem *item = genList->takeItem(i);

    delete item;
    delete genItem;
}

void ConfigView::update()
{
	// restore config from configdata
	// restore tran setting
	for(int i = 0; i < N_TRANSACTIONS; i ++){
		TranItem *item = (TranItem *)(tranList->itemWidget(tranList->item(i)));
		item->setTranSetting(m_configData->getTranSetting(i));
	}

	// restore time setting
	timeSetting->setTimeSetting(m_configData->getDuration(), m_configData->getIncUser(), m_configData->getIncTime());

	// restore server IP and update rate
	ipLineEdit->setText(QString(m_configData->getServerIP().c_str()));
	updateLineEdit->setText(QString::number(m_configData->getUpdateRate() * 5));

	// restore gen list
	for(int i = 0; i < MaxGenCount; i ++){
		if(m_configData->getGenConfig(i).userCount == -1) continue;

		this->addGen(i, m_configData->getGenConfig(i));
	}
}

// slots
void ConfigView::CheckHandle(int type, bool state)
{
    TTranSetting setting = m_configData->getTranSetting(type);
    setting.isOn = state;
    m_configController->setTranSetting(type, setting);
}

void ConfigView::RatioHandle(int type, int ratio)
{
    TTranSetting setting = m_configData->getTranSetting(type);
    setting.ratio = ratio;
    m_configController->setTranSetting(type, setting);
}

void ConfigView::DurationHandle(int sec)
{
    m_configController->setDuration(sec);
}

void ConfigView::UserHandle(int user)
{
    m_configController->setIncUser(user);
}

void ConfigView::TimeHandle(int time)
{
    m_configController->setIncTime(time);
}

void ConfigView::AddGenHandle()
{
    m_configController->addGen();
}

void ConfigView::DelGenHandle(int genId)
{
    // delete from data
    m_configController->delGen(genId);

    this->delGen(genId);
}

void ConfigView::GenConfigHandle(int genId, const TGenConfig &config)
{
    m_configController->setGenConfig(genId, config);
}

void ConfigView::SetServerIPHandle()
{
	QLineEdit *sender = (QLineEdit *)this->sender();
	QString text = sender->text();
	QStringList list = text.split('.', QString::SkipEmptyParts);
	if(text != "localhost" && list.count() != 4) return;
	
	m_configController->setServerIP(text.toStdString());
}

void ConfigView::SetUpdateRateHandle()
{
	QLineEdit *sender = (QLineEdit *)this->sender();
	QString text = sender->text();
	bool ok;
	int rate = text.toInt(&ok, 10);
	// conversion failed
	if(!ok){
		qDebug() << "ConfigView::SetUpdateRateHandle() text.toInt() failed, with text = " << text;
		return;
	}
	m_configController->setUpdateRate(rate);
}
